/*   1:    */ package nl.siegmann.epublib.search;
/*   2:    */ 
/*   3:    */ import java.io.IOException;
/*   4:    */ import java.io.Reader;
/*   5:    */ import java.text.Normalizer;
/*   6:    */ import java.text.Normalizer.Form;
/*   7:    */ import java.util.ArrayList;
/*   8:    */ import java.util.List;
/*   9:    */ import java.util.Scanner;
/*  10:    */ import java.util.regex.Matcher;
/*  11:    */ import java.util.regex.Pattern;
/*  12:    */ import nl.siegmann.epublib.domain.Book;
/*  13:    */ import nl.siegmann.epublib.domain.Resource;
/*  14:    */ import nl.siegmann.epublib.service.MediatypeService;
/*  15:    */ import org.apache.commons.lang.StringEscapeUtils;
/*  16:    */ import org.apache.commons.lang.StringUtils;
/*  17:    */ import org.slf4j.Logger;
/*  18:    */ import org.slf4j.LoggerFactory;
/*  19:    */ 
/*  20:    */ public class SearchIndex
/*  21:    */ {
/*  22: 29 */   private static final Logger log = LoggerFactory.getLogger(SearchIndex.class);
/*  23: 31 */   public static int NBSP = 160;
/*  24: 34 */   private static final Pattern WHITESPACE_PATTERN = Pattern.compile("[\\p{Z}\\s]+");
/*  25: 36 */   private static final Pattern REMOVE_ACCENT_PATTERN = Pattern.compile("\\p{InCombiningDiacriticalMarks}+");
/*  26: 38 */   private List<ResourceSearchIndex> resourceSearchIndexes = new ArrayList();
/*  27:    */   private Book book;
/*  28:    */   
/*  29:    */   public SearchIndex() {}
/*  30:    */   
/*  31:    */   public SearchIndex(Book book)
/*  32:    */   {
/*  33: 45 */     initBook(book);
/*  34:    */   }
/*  35:    */   
/*  36:    */   public Book getBook()
/*  37:    */   {
/*  38: 49 */     return this.book;
/*  39:    */   }
/*  40:    */   
/*  41:    */   private static class ResourceSearchIndex
/*  42:    */   {
/*  43:    */     private String content;
/*  44:    */     private Resource resource;
/*  45:    */     
/*  46:    */     public String getContent()
/*  47:    */     {
/*  48: 58 */       return this.content;
/*  49:    */     }
/*  50:    */     
/*  51:    */     public Resource getResource()
/*  52:    */     {
/*  53: 62 */       return this.resource;
/*  54:    */     }
/*  55:    */     
/*  56:    */     public ResourceSearchIndex(Resource resource, String searchContent)
/*  57:    */     {
/*  58: 66 */       this.resource = resource;
/*  59: 67 */       this.content = searchContent;
/*  60:    */     }
/*  61:    */   }
/*  62:    */   
/*  63:    */   private static ResourceSearchIndex createResourceSearchIndex(Resource resource)
/*  64:    */   {
/*  65: 72 */     String searchContent = getSearchContent(resource);
/*  66: 73 */     if (StringUtils.isBlank(searchContent)) {
/*  67: 74 */       return null;
/*  68:    */     }
/*  69: 76 */     ResourceSearchIndex searchIndex = new ResourceSearchIndex(resource, searchContent);
/*  70: 77 */     return searchIndex;
/*  71:    */   }
/*  72:    */   
/*  73:    */   public void initBook(Book book)
/*  74:    */   {
/*  75: 81 */     this.resourceSearchIndexes = createSearchIndex(book);
/*  76:    */   }
/*  77:    */   
/*  78:    */   private static List<ResourceSearchIndex> createSearchIndex(Book book)
/*  79:    */   {
/*  80: 85 */     List<ResourceSearchIndex> result = new ArrayList();
/*  81: 86 */     if (book == null) {
/*  82: 87 */       return result;
/*  83:    */     }
/*  84: 89 */     for (Resource resource : book.getContents())
/*  85:    */     {
/*  86: 90 */       ResourceSearchIndex resourceSearchIndex = createResourceSearchIndex(resource);
/*  87: 91 */       if (resourceSearchIndex != null) {
/*  88: 92 */         result.add(resourceSearchIndex);
/*  89:    */       }
/*  90:    */     }
/*  91: 95 */     return result;
/*  92:    */   }
/*  93:    */   
/*  94:    */   public SearchResults doSearch(String searchTerm)
/*  95:    */   {
/*  96: 99 */     SearchResults result = new SearchResults();
/*  97:100 */     if (StringUtils.isBlank(searchTerm)) {
/*  98:101 */       return result;
/*  99:    */     }
/* 100:103 */     searchTerm = cleanText(searchTerm);
/* 101:104 */     for (ResourceSearchIndex resourceSearchIndex : this.resourceSearchIndexes) {
/* 102:105 */       result.addAll(doSearch(searchTerm, resourceSearchIndex));
/* 103:    */     }
/* 104:107 */     result.setSearchTerm(searchTerm);
/* 105:108 */     return result;
/* 106:    */   }
/* 107:    */   
/* 108:    */   public static String getSearchContent(Resource resource)
/* 109:    */   {
/* 110:113 */     if (resource.getMediaType() != MediatypeService.XHTML) {
/* 111:114 */       return "";
/* 112:    */     }
/* 113:116 */     String result = "";
/* 114:    */     try
/* 115:    */     {
/* 116:118 */       result = getSearchContent(resource.getReader());
/* 117:    */     }
/* 118:    */     catch (IOException e)
/* 119:    */     {
/* 120:120 */       log.error(e.getMessage());
/* 121:    */     }
/* 122:122 */     return result;
/* 123:    */   }
/* 124:    */   
/* 125:    */   public static String getSearchContent(Reader content)
/* 126:    */   {
/* 127:127 */     StringBuilder result = new StringBuilder();
/* 128:128 */     Scanner scanner = new Scanner(content);
/* 129:129 */     scanner.useDelimiter("<");
/* 130:130 */     while (scanner.hasNext())
/* 131:    */     {
/* 132:131 */       String text = scanner.next();
/* 133:132 */       int closePos = text.indexOf('>');
/* 134:133 */       String chunk = text.substring(closePos + 1).trim();
/* 135:134 */       chunk = StringEscapeUtils.unescapeHtml(chunk);
/* 136:135 */       chunk = cleanText(chunk);
/* 137:136 */       result.append(chunk);
/* 138:    */     }
/* 139:138 */     return result.toString();
/* 140:    */   }
/* 141:    */   
/* 142:    */   private static boolean isHtmlWhitespace(int c)
/* 143:    */   {
/* 144:148 */     return (c == NBSP) || (Character.isWhitespace(c));
/* 145:    */   }
/* 146:    */   
/* 147:    */   public static String unicodeTrim(String text)
/* 148:    */   {
/* 149:152 */     int leadingWhitespaceCount = 0;
/* 150:153 */     int trailingWhitespaceCount = 0;
/* 151:154 */     for (int i = 0; i < text.length(); i++)
/* 152:    */     {
/* 153:155 */       if (!isHtmlWhitespace(text.charAt(i))) {
/* 154:    */         break;
/* 155:    */       }
/* 156:158 */       leadingWhitespaceCount++;
/* 157:    */     }
/* 158:160 */     for (int i = text.length() - 1; i > leadingWhitespaceCount; i--)
/* 159:    */     {
/* 160:161 */       if (!isHtmlWhitespace(text.charAt(i))) {
/* 161:    */         break;
/* 162:    */       }
/* 163:164 */       trailingWhitespaceCount++;
/* 164:    */     }
/* 165:166 */     if ((leadingWhitespaceCount > 0) || (trailingWhitespaceCount > 0)) {
/* 166:167 */       text = text.substring(leadingWhitespaceCount, text.length() - trailingWhitespaceCount);
/* 167:    */     }
/* 168:169 */     return text;
/* 169:    */   }
/* 170:    */   
/* 171:    */   public static String cleanText(String text)
/* 172:    */   {
/* 173:183 */     text = unicodeTrim(text);
/* 174:    */     
/* 175:    */ 
/* 176:186 */     Matcher matcher = WHITESPACE_PATTERN.matcher(text);
/* 177:187 */     text = matcher.replaceAll(" ");
/* 178:    */     
/* 179:    */ 
/* 180:190 */     text = Normalizer.normalize(text, Normalizer.Form.NFD);
/* 181:    */     
/* 182:    */ 
/* 183:193 */     text = REMOVE_ACCENT_PATTERN.matcher(text).replaceAll("");
/* 184:    */     
/* 185:    */ 
/* 186:196 */     text = text.toLowerCase();
/* 187:197 */     return text;
/* 188:    */   }
/* 189:    */   
/* 190:    */   private static List<SearchResult> doSearch(String searchTerm, ResourceSearchIndex resourceSearchIndex)
/* 191:    */   {
/* 192:202 */     return doSearch(searchTerm, resourceSearchIndex.getContent(), resourceSearchIndex.getResource());
/* 193:    */   }
/* 194:    */   
/* 195:    */   protected static List<SearchResult> doSearch(String searchTerm, String content, Resource resource)
/* 196:    */   {
/* 197:206 */     List<SearchResult> result = new ArrayList();
/* 198:207 */     int findPos = content.indexOf(searchTerm);
/* 199:208 */     while (findPos >= 0)
/* 200:    */     {
/* 201:209 */       SearchResult searchResult = new SearchResult(findPos, searchTerm, resource);
/* 202:210 */       result.add(searchResult);
/* 203:211 */       findPos = content.indexOf(searchTerm, findPos + 1);
/* 204:    */     }
/* 205:213 */     return result;
/* 206:    */   }
/* 207:    */ }


/* Location:           C:\Users\David\workspace\CosaRaraPorqueSi\main\epublib-tools-3.1.jar
 * Qualified Name:     nl.siegmann.epublib.search.SearchIndex
 * JD-Core Version:    0.7.0.1
 */